#!/usr/bin/env python
# _*_ coding: utf-8 _*_
# @Time : 2020/7/22 21:47
# @Author : LZQ
# @Version：V 0.1
# @File : categories.py
# @desc :
from . import api, categorie
from app.utils.status_code import RET
from app.token_verify import verify
from flask import request, current_app, g, jsonify
from flask_sqlalchemy import Pagination
from sqlalchemy import and_, or_, desc
from app.utils.tree import get_tree
from app.models import Category, Attribute
from __init__ import redis_store, db

import json


@categorie.route("/list", methods=['GET'])
@verify
def get_categories():
    data = request.args if request.args else {}
    type_id = int(data.get("type") if data.get("type") else 0)
    pagesize = data.get("pagesize") if data.get("pagesize") else None
    pagenum = data.get("pagenum") if data.get("pagenum") else None
    res_dict = cat_paginate(pagenum, pagesize, type_id)
    print(res_dict)
    return jsonify(res_dict)


def cat_paginate(pagenum, pagesize, type_id):
    '''
    获取商品分类信息
    :param pagenum: 当前页数
    :param pagesize: 当前页面显示条数
    :return: 分页后的数据
    '''
    res_dict = {}
    list = []
    try:
        if pagesize and pagenum:
            pagesize = int(pagesize)
            pagenum = int(pagenum)
            categorys = Category.query.filter(
                Category.cat_level == type_id - 1 if type_id else Category.cat_level.in_(['0', ])).paginate(pagenum,
                                                                                                            pagesize)
            list = get_cate_tree(categorys)
            res_dict = {"data": list, "meta": RET.SUCCESS, "total": categorys.total}
        else:
            try:
                list = json.loads(redis_store.hget("cate_list", "cates"))
            except Exception as e:
                current_app.logger.error(e)

            if len(list) == 0:
                categorys = Category.query.filter(
                    Category.cat_level == type_id - 1 if type_id else Category.cat_level.in_(['0', '1', '2'])).all()
                list = get_cate_tree(categorys)
                try:
                    redis_store.hset("cate_list", "cates", json.dumps(list))
                except Exception as e:
                    current_app.logger.error(e)

            res_dict = {"data": list, "meta": RET.FAIL}
    except Exception as e:
        current_app.logger.error(e)
        res_dict = {"data": [], "meta": {}}
    return res_dict


# 将分类参数列表变为树形结构
def get_cate_tree(*kwargs):
    list1 = []
    list2 = []
    list3 = []
    data = []
    categorys = None
    if kwargs:
        categorys = kwargs[0]
    for category in categorys.items if isinstance(categorys, Pagination) else categorys:
        if category.cat_level == 0:
            category_level_2s = Category.query.filter(Category.cat_level == 1,
                                                      and_(Category.cat_pid == category.cat_id)).all()
            for category2 in category_level_2s:
                category_level_3s = Category.query.filter(Category.cat_level == 2,
                                                          and_(Category.cat_pid == category2.cat_id)).all()
                for category3 in category_level_3s:
                    list3.append(category3)
                list2.append(category2)
            list1.append(category)
        elif category.cat_level == 1:
            category_level_3s = Category.query.filter(Category.cat_level == 2,
                                                      and_(Category.cat_pid == category.cat_id)).all()
            for category3 in category_level_3s:
                list3.append(category3)
            list2.append(category)
        elif category.cat_level == 2:
            list3.append(category)
    if len(list1) != 0:
        for category_1 in list1:
            category_1_dict = category_1.to_dict()
            category_1_dict['children'] = []
            for category_2 in list2:
                category_2_dict = category_2.to_dict()
                category_2_dict['children'] = []
                for category_3 in list3:
                    if category_3.cat_pid == category_2.cat_id:
                        category_2_dict['children'].append(category_3.to_dict())
                if category_2.cat_pid == category_1.cat_id:
                    category_1_dict['children'].append(category_2_dict)
            data.append(category_1_dict)
    elif len(list2) != 0:
        for category_2 in list2:
            category_2_dict = category_2.to_dict()
            category_2_dict['children'] = []
            for category_3 in list3:
                if category_3.cat_pid == category_2.cat_id:
                    category_2_dict['children'].append(category_3.to_dict())
            data.append(category_2_dict)
    elif len(list3) != 0:
        for category_3 in list3:
            data.append(category_3.to_dict())
    return data


@categorie.route("/add", methods=['POST'])
@verify
def addCate():
    '''
    添加商品分类
    :return:
    '''
    data = json.loads(request.get_data())
    cat_name = data.get("cat_name")
    cat_pid = data.get('cat_pid') if data.get('cat_pid') else '0'
    cat_level = data.get("cat_level") if data.get("cat_level") else '0'
    if not all([cat_name, cat_level, cat_pid]):
        return jsonify(RET.PARAMS_NOTALL)
    try:
        category = Category()
        category.cat_name = cat_name
        category.cat_pid = cat_pid
        category.cat_deleted = 0
        category.cat_level = cat_level
        db.session.add(category)
        db.session.commit()
        print(cat_level)
        if cat_level <= 2:
            try:
                redis_store.hdel("type_{}".format(int(cat_level) - 1), "parentList")
            except Exception as e:
                current_app.logger.error(e)
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(RET.GOODS_ADD_CATEGORYS_FAIL)
    return jsonify(RET.GOODS_ADD_CATEGORYS_SUCCESS)


@categorie.route("/<int:cat_id>/delCate", methods=["DELETE"])
@verify
def del_category(cat_id):
    '''
    删除商品分类
    :param cat_id:
    :return:
    '''
    # data = json.loads(request.get_data())
    # cat_id  = data.get("cat_id")
    try:
        category = Category.query.filter(Category.cat_id == cat_id).first()
        category.cat_deleted = 1
        childrens = Category.query.filter(Category.cat_pid == cat_id).all()
        if childrens:
            for children_category in childrens:
                count_1 = Category.query.filter(Category.cat_id == children_category.cat_id).update({"cat_deleted": 1})
        cat_dict = get_tirgger_deleted(category)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify({'data': [], 'meta': RET.GOODS_DELETE_CATEGORYS_FAIL})
    try:
        redis_store.hdel("type_{}".format(2 if category.cat_level == 0 else 1), "parentList")
    except Exception as e:
        current_app.logger.error(e)
    return jsonify({'data': cat_dict, 'meta': RET.GOODS_DELETE_CATEGORYS_SUCCESS})


@categorie.route("/<int:cat_id>/putCate", methods=["PUT"])
@verify
def put_category(cat_id):
    '''
    恢复商品分类
    :param cat_id:
    :return:
    '''
    # data = json.loads(request.get_data())
    # cat_id  = data.get("cat_id")
    try:
        category = Category.query.filter(Category.cat_id == cat_id).first()
        category.cat_deleted = 0
        childrens = Category.query.filter(Category.cat_pid == cat_id).all()
        if childrens:
            for children_category in childrens:
                count_1 = Category.query.filter(Category.cat_id == children_category.cat_id).update({"cat_deleted": 0})
        cat_dict = get_tirgger_deleted(category)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify({'data': [], 'meta': RET.GOODS_PUT_CATEGORYS_FAIL})
    try:
        redis_store.hdel("type_{}".format(2 if category.cat_level == 0 else 1), "parentList")
    except Exception as e:
        current_app.logger.error(e)
    return jsonify({'data': cat_dict, 'meta': RET.GOODS_PUT_CATEGORYS_SUCCESS})


@categorie.route("/update", methods=["POST"])
@verify
def update_category():
    '''
    更新商品分类
    :param cat_id:
    :return:
    '''
    data = json.dumps(request.get_data())
    cat_id = data.get("cat_id")
    cat_name = data.get("cat_name")
    cat_pid = data.get("cat_name")
    cat_src = data.get("cat_src")
    cat_icon = data.get("cat_icon")
    cat_level = data.get("cat_level")
    params = {"cat_name": cat_name, "cat_pid": cat_pid, "cat_src": cat_src, "cat_icon": cat_icon,
              "cat_level": cat_level}
    try:
        count = Category.query.filter(Category.cat_id == cat_id).update(params)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(RET.GOODS_DELETE_CATEGORYS_FAIL)
    if count == 0:
        return jsonify(RET.GOODS_DELETE_CATEGORYS_FAIL)
    return jsonify(RET.GOODS_DELETE_CATEGORYS_SUCCESS)


def get_parents(categorys, type_ip):
    list1 = []
    list2 = []
    data = []
    for category in categorys:
        if type_ip == 2:
            category_level_2s = Category.query.filter(Category.cat_level == 1,
                                                      and_(Category.cat_pid == category.cat_id)).all()
            for category2 in category_level_2s:
                list2.append(category2)
            list1.append(category)
        if type_ip == 1:
            list2.append(category)

    if len(list1) != 0:
        for category_1 in list1:
            category_1_dict = category_1.to_dict()
            category_1_dict['children'] = []
            for category_2 in list2:
                category_2_dict = category_2.to_dict()
                if category_2.cat_pid == category_1.cat_id:
                    category_1_dict['children'].append(category_2_dict)
            data.append(category_1_dict)
    if len(list2) != 0:
        for category_2 in list2:
            category_2_dict = category_2.to_dict()
            data.append(category_2_dict)
    return data


@categorie.route("/parents", methods=['GET'])
@verify
def get_parent_list():
    data = request.args if request.args else ()
    if data:
        type_id = int(data.get("type"))
        print(type_id)
        if type_id == 1:
            res_dict = get_parent_tree(type_id - 1, 1)
        elif type_id == 2:
            res_dict = get_parent_tree(type_id - 2, 2)
        else:
            return jsonify({'data': [], 'meta': {"code": 400, "msg": "当前分类参数是顶级分类不需要父级分类"}})
        return jsonify(res_dict)
    else:
        return jsonify({'data': [], 'meta': {"code": 401, "msg": "缺少参数"}})


def get_parent_tree(type_id, type_ip):
    list = []
    res_dict = {"data": [], "meta": RET.GOODS_GET_PARENTS_FAIL}
    cate_list = []
    try:
        list = json.loads(redis_store.hget("type_{}".format(type_ip), "parentList"))
    except Exception as e:
        current_app.logger.error(e)
    if len(list):
        res_dict = {"data": list, "meta": RET.SUCCESS}
    else:
        categorys = Category.query.filter(
            Category.cat_level == type_id).all()
        if categorys:
            cate_list = get_parents(categorys, type_ip)
            res_dict = {"data": cate_list, "meta": RET.SUCCESS}
        else:
            res_dict = {"data": [], "meta": RET.SUCCESS}
    if len(cate_list):
        try:
            redis_store.hset("type_{}".format(type_ip), "parentList", json.dumps(cate_list))
            pass
        except Exception as e:
            current_app.logger.error(e)
    return res_dict


def get_tirgger_deleted(category):
    '''
    恢复删除分类后，返回当前分类的数据
    :param category:
    :return:
    '''
    cat_dict = category.to_dict()
    categorys = Category.query.filter(Category.cat_pid == category.cat_id).all()
    if categorys:
        cat_dict['children'] = []
        for category_c in categorys:
            cat_dict['children'].append(category_c.to_dict())
    return cat_dict


@categorie.route("/catetype", methods=['GET'])
def get_type_cate():
    tree = []
    try:
        tree = json.loads(redis_store.hget("catetype", "catetype"))
    except Exception as e:
        current_app.logger.error(e)
    categorys = Category.query.filter().all()
    if len(tree):
        data = {"data": tree, "meta": {"code": 200, "msg": "获取分类参数成功"}}
        return jsonify(data)
    else:
        tree = get_tree(categorys)
        try:
            redis_store.hset("catetype", "catetype", json.dumps(tree))
        except Exception as e:
            current_app.logger.error(e)
    data = {"data": tree, "meta": {"code": 200, "msg": "获取分类参数成功"}}
    return jsonify(data)


@categorie.route("/<int:cat_id>/<string:sel>/attributes")
@verify
def get__attributes(cat_id,sel):
    data = get_attributes(cat_id,sel)
    if len(data):
        dict = {"data": data, "meta": {"code": 200, "msg": "获取分类参数列表成功"}}
    else:
        dict = {"data": data, "meta": {"code": 400, "msg": "获取分类参数列表失败"}}
    return jsonify(dict)

def get_attributes(cat_id, sel):
    data = []
    try:
        attributes = Attribute.query.filter(Attribute.cat_id == cat_id, and_(Attribute.attr_sel == sel)).all()
        for attribute in attributes:
            data.append(attribute.to_dict())
    except Exception as e:
        current_app.logger.error(e)
    return data
@categorie.route("add/attr",methods=['POST'])
@verify
def add_cate():
    cate_data = json.loads(request.get_data())
    attr_name = cate_data.get("attr_name")
    cat_id = cate_data.get("cat_id")
    attr_sel = cate_data.get("attr_sel")
    attr_write = cate_data.get("attr_write")
    data={}
    attribute =  Attribute()
    attribute.attr_name = attr_name
    attribute.cat_id = cat_id
    attribute.attr_sel = attr_sel
    attribute.attr_write = attr_write
    try:
        db.session.add(attribute)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        data = {"code": 400, "msg": "添加参数错误"}
        return jsonify(data)
    attr_dict = attribute.to_dict()
    attr_dict['inputValue'] = ''
    data = {"data":attr_dict,"meta":{"code": 200, "msg": "添加参数成功"}}
    return jsonify(data)

@categorie.route("/updateValues",methods = ['POST'])
@verify
def update_valus():
    data = json.loads(request.get_data()) if request.get_data() else {}
    data_dict = data_dict = {"code":400,"msg":"跟新失败"}
    print(request.get_data)
    attr_id = data.get("attr_id")
    attr_valus = data.get("attr_vals")
    attr_str_valus = ''
    if attr_valus and attr_id:
        for attr_value in attr_valus:
            if attr_value!=attr_valus[-1]:
                attr_str_valus += attr_value + ' '
            else:
                attr_str_valus+=attr_value
    try:
        attr = Attribute.query.filter(Attribute.attr_id==attr_id).first()
        attr.attr_vals = attr_str_valus
        print(attr_str_valus)
        db.session.commit()
        data_dict = {"data": attr.to_dict(), "meta": {"code": 200, "msg": "更新参数值成功"}}
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
    return jsonify(data_dict)

@categorie.route("/edit",methods=['POST'])
@verify
def edit_attribute():
    data =  json.loads(request.get_data()) if request.get_data() else {}
    data_dict = {}
    attr_name = data.get("attr_name")
    attr_id = data.get("attr_id")
    if not all([attr_id,attr_name]):
        return jsonify()
    try:
        attribute = Attribute.query.filter(Attribute.attr_id==attr_id).first()
        if attribute:
            attribute.attr_name = attr_name
            db.session.commit()
            data_dict = {"data":get_attributes(attribute.cat_id,attribute.attr_sel),"meta":{"code":200,"msg":"更新成功"}}
        else:
            data_dict =  {"data":[],"meta":{"code":400,"msg":"更新成功"}}
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        data_dict= {"data":[],"meta":{"code":400,"msg":"更新成功"}}
    return jsonify(data_dict)

@categorie.route("/del",methods=['POST'])
@verify
def del_attribute():
    data =  json.loads(request.get_data()) if request.get_data() else {}
    data_dict = {}
    attr_id = int(data.get("attr_id")) if data.get("attr_id") else None
    cat_id = data.get("cat_id")
    attr_sel = data.get("attr_sel")
    try:
        attribute = Attribute.query.filter(Attribute.attr_id==attr_id).first()
        attribute.delete()
        db.session.commit()
        data_dict = {"data":get_attributes(cat_id,attr_sel),"meta":{"code":200,"msg":"删除成功"}}
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        data_dict = {"data":[],"meta":{"code":400,"msg":"删除失败"}}
    return jsonify(data_dict)

@categorie.route("/attrNameIsExist",methods=['POST'])
@verify
def attr_name_is_exist():
    data = json.loads(request.get_data()) if request.get_data() else {}
    attr_name = data.get("attr_name")
    cat_id = data.get("cat_id")
    data_dict = {}
    count = 0
    try:
        count = Attribute.query.filter(Attribute.attr_name==attr_name,and_(Attribute.cat_id==cat_id)).count()
    except Exception as e:
        current_app.logger.error(e)
    if count!=0:
        data_dict={"code":200,"isExist":"true"}
    else:
        data_dict = {"code": 200, "isExist": "false"}
    return jsonify(data_dict)